﻿namespace Beetle
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;

    public abstract class HeadSizeOfPackage : Package
    {
        private int _field_a;
        private byte[] _field_b;
        private int _field_c;
        private int _field_d;

        public HeadSizeOfPackage()
        {
            this._field_b = new byte[4];
        }

        public HeadSizeOfPackage(TcpChannel channel) : base(channel)
        {
            this._field_b = new byte[4];
        }

        public override void Import(byte[] data, int start, int count)
        {
            this._field_d = count;
            while (this._field_d > 0)
            {
                if (this._field_a == 0)
                {
                    if (this._field_d < 4)
                    {
                        this._field_c = this._field_d;
                        Buffer.BlockCopy(data, start, this._field_b, 0, this._field_d);
                        this._field_d = 0;
                        return;
                    }
                    base.Writer.Reset();
                    if (this._field_c == 0)
                    {
                        this._field_a = BitConverter.ToInt32(data, start);
                        if ((this._field_a > TcpUtils.DataPacketMaxLength) || (this._field_a <= 0))
                        {
                            throw NetTcpException.DataOverflow();
                        }
                        base.Writer.Write(data, start, 4);
                        start += 4;
                        this._field_a -= 4;
                        this._field_d -= 4;
                    }
                    else
                    {
                        int num = 4 - this._field_c;
                        Buffer.BlockCopy(data, start, this._field_b, this._field_c, num);
                        this._field_c = 0;
                        this._field_a = BitConverter.ToInt32(this._field_b, 0);
                        if ((this._field_a > TcpUtils.DataPacketMaxLength) || (this._field_a <= 0))
                        {
                            throw NetTcpException.DataOverflow();
                        }
                        base.Writer.Write(this._field_b, 0, 4);
                        start += num;
                        this._field_a -= 4;
                        this._field_d -= num;
                    }
                }
                if (this._field_d >= this._field_a)
                {
                    base.Writer.Write(data, start, this._field_a);
                    this.OnMessageDataReader(base.Writer);
                    start += this._field_a;
                    this._field_d -= this._field_a;
                    this._field_a = 0;
                }
                else
                {
                    base.Writer.Write(data, start, this._field_d);
                    this._field_a -= this._field_d;
                    this._field_d = 0;
                }
            }
        }

        public override IMessage MessageRead(BufferReader reader)
        {
            IMessage message = null;
            object obj2;
            reader.Read(4);
            message = this.ReadMessageByType(reader, out obj2);
            if (message == null)
            {
                throw NetTcpException.TypeNotFound(obj2.ToString());
            }
            try
            {
                message.Load(reader);
            }
            catch (Exception exception)
            {
                throw NetTcpException.ObjectLoadError(obj2.ToString(), exception);
            }
            return message;
        }

        public override void MessageWrite(IMessage msg, BufferWriter writer)
        {
            int num = writer._field_e;
            IList<ByteArraySegment> refdata = writer.WriteHeadSize();
            this.WriteMessageType(msg, writer);
            msg.Save(writer);
            writer.SetHeadSize(writer.Count - num, refdata);
        }

        protected override void OnDisposed()
        {
            base.OnDisposed();
        }

        protected abstract IMessage ReadMessageByType(BufferReader reader, out object typeTag);
        protected abstract void WriteMessageType(IMessage msg, BufferWriter writer);
    }
}

